#include "pwext.hpp"
#include <list>

// [[ex05fa]]
// DEBUG descr A simple-minded implementation of weak references causes the memory corruption.
class someobj
{
public:
	someobj() : other_(0)
	{ }

	void linkOther(someobj *ob)
	{
		pw::lockmutex lm(mutex_);
		other_ = ob;
	}
	void unlinkOther()
	{
		pw::lockmutex lm(mutex_);
		other_ = 0;
	}
	someobj *getOther()
	{
		return other_;
	}
	bool someMethod()
	{
		pw::lockmutex lm(mutex_);
		// here it does something....
		return true;
	}
protected:
	pw::pmutex mutex_;
	someobj *other_;
};

// DEBUG from
void makeWorkerThread(someobj *o);

void run()
{
// DEBUG to
// ... creation ...
	someobj *a = new someobj;
	someobj *b = new someobj;
	a->linkOther(b);
	b->linkOther(a);
	makeWorkerThread(a);
	makeWorkerThread(b);

// DEBUG from
}

class worker : public pw::pwthread
{
public:
	worker(someobj *o) :
		o_(o)
	{ }

   virtual void *execute()
   {
// DEBUG to
// ... in the worker thread ...
// the thread keeps the someobj in the member o_
	someobj *other;
	// ... call a method on the other object ...
	bool result;
	other = o_->getOther();
	if (other)
		result = other->someMethod();
	else
		result = false;
	// ... destroy our object ...
	other = o_->getOther();
	if (other)
		other->unlinkOther();
	delete o_;
// END
// DEBUG from
	o_ = 0;
	return 0;
	}
protected:
	someobj *o_;
};

std::list <worker *> workers;

void makeWorkerThread(someobj *o)
{
	workers.push_back(new worker(o));
}

